#ifndef SUBSETS_H
#define SUBSETS_H


#define SS_MAXEL 500

typedef unsigned int Block;

#define SS_NOELSINBLOCK (sizeof(Block)*8)
#define SS_NOBLOCKS \
(\
(SS_MAXEL/SS_NOELSINBLOCK) + \
(((SS_MAXEL%SS_NOELSINBLOCK) > 0)?1:0)\
)

#define SS_NAME_MAX_LEN 1000
#define SS_NAME_DIM ((SS_NAME_MAX_LEN) +1)

typedef struct subset
{
  char name[SS_NAME_DIM];
  unsigned int ss_of;
  Block ss_blocks[SS_NOBLOCKS];
 
} Subset;

#define SS_FORALLIN(i,ptr)\
for((i)=0;i<(ptr)->ss_of;i++) if(ss_belongs((i),(ptr))) \

/* Basic operations */

extern char *
ss_name(Subset *);

extern void
ss_set_name(Subset *,char *);

extern void
ss_cat_name(Subset *,char *);

extern void 
ss_add_name(Subset *, char *name, char *sep);

extern int
ss_cmp_name(Subset *s,char *n);

extern void 
ss_free(Subset * s);

/** Initialize a subset of n els as the empty one. */ 
extern void
ss_empty(int n,Subset *s);

/** Initialize a subset of n els as the total one. */ 
extern void
ss_total(int n,Subset *s);

/** Initialize a subset of n els at random. */ 
void
ss_random(int n,Subset *s);

/** Intersection. */ 
void
ss_intersection(Subset *dest,Subset *s1,Subset *s2);

/** Union. */ 
void
ss_union(Subset *dest,Subset *s1,Subset *s2);

/** Cardinality */
extern int 
ss_card(Subset * s);

/** Copying. */ 
void
ss_cpy(Subset *dest,Subset *s);

/** Add element j to subset s. */ 
extern void
ss_addto(Subset *s,int j);

/** Delete  element j from subset s. */ 
extern void
ss_delfrom(Subset *s,int j);

/** Turn into the complement. */
void
ss_complement(Subset *s);

/** Are they equal. */ 
extern int 
ss_equal(Subset *s1,Subset *s2);

/** Is s1 contained in s2.  */ 
extern int 
ss_contained(Subset *s1,Subset *s2);

/** Does j belongs to s. */ 
extern int 
ss_belongs(int j,Subset *s);

/** Printing utility. */
void
ss_print(Subset *s);

void
ss_print_name(Subset *s);

#endif /* SUBSETS_H */
